﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Wicture.DbRESTFul;
using Wicture.DbRESTFul.SQL;
using Wicture.EPC.Common;
using Wicture.EPC.Service.V1.Filters;
using Wicture.EPC.Service.V1.Repository;
using Wicture.EPC.Service.V1.Resources;

namespace Wicture.EPC.Service.V1.QueryInterceptors.Interceptors
{
    public class MoparQueryInterceptor : BaseQueryInterceptor
    {
        private readonly string[] brandCodes = new string[] { "chrysler", "jeep", "dodge", "fiat", "plymouth" };
        public override string[] BrandCodes => brandCodes;
        protected override List<Query_MainGroupResult> GetMainGroup(DbRESTFulRepository repository, JObject param)
        {
           return repository.Invoke<Query_MainGroupResult>(CSIs.Query_Main_Group_For_Filter, param);
        }
        protected override List<Query_MainGroupResult> FilterMainGroupsByVin(DbRESTFulRepository repository, List<Query_MainGroupResult> results, string vin)
        {
            if (string.IsNullOrEmpty(vin))
            {
                return results;
            }
            else
            {
                var vinInfo = QueryVinByCode(repository, new Get_Model_InfoParam { vin = vin });
                if (vinInfo == null)
                {
                    throw new LogicalException("vin不存在!", 610);
                }
                var option = MoparFilter.GetVinFilterOption(vinInfo);
                foreach(var mainGroup in results)
                {
                    MoparFilter filter = new MoparFilter(mainGroup.maingroupFilterCode);
                    if (!filter.IsMath(option))
                    {
                        mainGroup.isBelongTo = false;
                    }
                }
                return results.Where(q => q.isBelongTo).ToList();
            }
        }

        protected override dynamic QueryVinByCode(DbRESTFulRepository repository, Get_Model_InfoParam param)
        {
            return repository.Invoke(CSIs.Query_Vin_By_Code_For_Mopar, param);
        }
        protected override List<Get_Model_InfoResult._props> GetVinProps(DbRESTFulRepository repository, dynamic vin)
        {
            //车型，车系，年款，版本，车架号，品牌，品牌代码，变速箱，车身颜色，发动机，发动机类型，排量，生产日期
            string engineCode = vin.engineCode;
            string transCode = vin.transCode;
            string engineDesc = ResourceHelper.MoparFeatureDict.ContainsKey(engineCode) ? ResourceHelper.MoparFeatureDict[engineCode] : "";
            string transDesc = ResourceHelper.MoparFeatureDict.ContainsKey(transCode) ? ResourceHelper.MoparFeatureDict[transCode] : "";
            List<Get_Model_InfoResult._props> props = new List<Get_Model_InfoResult._props>();
            props.Add(new Get_Model_InfoResult._props { key = "车型", value = vin.name });
            props.Add(new Get_Model_InfoResult._props { key = "年款", value = vin.modelYear });
            props.Add(new Get_Model_InfoResult._props { key = "生产日期", value = vin.productionDate?.ToString() });
            props.Add(new Get_Model_InfoResult._props { key = "发动机", value = $"{engineCode} {engineDesc}" });
            props.Add(new Get_Model_InfoResult._props { key = "变速箱", value = $"{transCode} {transDesc}" });
            props.Add(new Get_Model_InfoResult._props { key = "Body Model Code", value = vin.bodyModelCode });
            props.Add(new Get_Model_InfoResult._props { key = "车架号", value = vin.vin });
            return props.Where(q => !string.IsNullOrEmpty(q.value)).ToList();
        }
        protected override List<Get_Model_InfoResult._features> GetVinFeatures(DbRESTFulRepository repository, dynamic vin)
        {
            string featureCodes = vin.featureCodes;
            if (!string.IsNullOrEmpty(featureCodes))
            {
                List<Get_Model_InfoResult._features> retList = new List<Get_Model_InfoResult._features>();
                for (int i = 0; i < featureCodes.Length; i = i + 3)
                {
                    string featureCode = featureCodes.Substring(i, 3);
                    retList.Add(new Get_Model_InfoResult._features() { key = featureCode, value = ResourceHelper.MoparFeatureDict.ContainsKey(featureCode) ? ResourceHelper.MoparFeatureDict[featureCode] : "" });
                }
                return retList.OrderBy(q=>q.key).ToList();
            }
            else
            {
                return null;
            }
        }

        protected override List<Query_PartsResult> GetParts(DbRESTFulRepository repository, JObject param)
        {
            return repository.Invoke<Query_PartsResult>(CSIs.Query_Parts_For_Mopar, param);
        }

        protected override void FilterPartsByVin(DbRESTFulRepository repository, ref List<Query_PartsResult> result, string vin, string selectorId)
        {
            if (string.IsNullOrEmpty(vin))
            {
                return;
            }
            var vinInfo = QueryVinByCode(repository, new Get_Model_InfoParam { vin = vin });
            if (vinInfo == null)
            {
                throw new LogicalException("vin不存在!", 610);
            }
            var option = MoparFilter.GetVinFilterOption(vinInfo);
            ISet<string> featureCodes = GetVinFeatureCodes(vinInfo);
            foreach (var usage in result)
            {
                MoparFilter filter = new MoparFilter(usage.modelFilter);
                usage.modelFilter = "";
                if (!filter.IsMath(option))
                {
                    usage.belongToVin = false;
                    continue;
                }
                if (string.IsNullOrEmpty(usage.featureCodes) || usage.featureCodes.Length < 3)
                {
                    usage.featureCodes = "";
                    continue;
                }
                UCStringMopar uCString = new UCStringMopar(usage.featureCodes);
                usage.featureCodes = "";
                if (!uCString.IsMatch(featureCodes))
                {
                    usage.belongToVin = false;
                    continue;
                }
            }
        }

        protected override List<Query_PartsResult> BuildPartResults(List<Query_PartsResult> result)
        {
            List<Query_PartsResult> ret = new List<Query_PartsResult>();
            var groupedParts = result.GroupBy(e => new { e.partCode, e.imageSN, e.quantity });
            foreach (var item in groupedParts)
            {
                var info = item.First();
                info.belongToVin = item.Any(q => q.belongToVin);
                ret.Add(info);
            }
            return ret;
        }

        private ISet<string> GetVinFeatureCodes(dynamic vinInfo)
        {
            ISet<string> set = new HashSet<string>();
            string engineCode = vinInfo.engineCode;
            string transCode = vinInfo.transCode;
            set.Add(engineCode);
            set.Add(transCode);
            string featureCodes = vinInfo.featureCodes;
            if (!string.IsNullOrEmpty(featureCodes))
            {
                for (int i = 0; i < featureCodes.Length; i = i + 3)
                {
                    string featureCode = featureCodes.Substring(i, 3);
                    set.Add(featureCode);
                }
            }
            return set;
        }

        protected override IEnumerable<Query_SubGroupResult> GetSubGroup(DbRESTFulRepository repository, JObject param)
        {
            return repository.Invoke<Query_SubGroupResult>(CSIs.Query_SubGroup_For_Mopar, param);
        }

        protected override List<Query_SubGroupResult> FilterSubGroupsByVin(DbRESTFulRepository repository, List<Query_SubGroupResult> results, JObject param)
        {
            var vin = param.Value<string>(ParamFields._vin);
            if (string.IsNullOrEmpty(vin) || results == null || results.Count == 0)
            {
                return results;
            }
            var vinInfo = QueryVinByCode(repository, new Get_Model_InfoParam { vin = vin });
            if (vinInfo == null)
            {
                throw new LogicalException("vin不存在!", 610);
            }
            var option = MoparFilter.GetVinFilterOption(vinInfo);
            foreach (var subGroup in results)
            {
                MoparFilter filter = new MoparFilter(subGroup.specCodes);
                subGroup.specCodes = "";
                if (!filter.IsMath(option))
                {
                    subGroup.belongTo = false;
                    continue;
                }
                filter = new MoparFilter(subGroup.subgroupFilterCode);
                subGroup.subgroupFilterCode = "";
                if (!filter.IsMath(option))
                {
                    subGroup.belongTo = false;
                    continue;
                }
            }
            return results;
        }

        protected override dynamic GetModelsByPart(DbRESTFulRepository repository, int pageIndex, int pageSize, string brandCode, string partCode)
        {
            return repository.Invoke(CSIs.Query_Models_By_Part_Standard, new { pageIndex, pageSize, brandCode, partCode });
        }

        public override object QueryPartDetail(DbRESTFulRepository repository, JObject param)
        {
            param.RemoveEmptyValues();
            var brandCode = param.Value<string>(ParamFields._brandCode);
            var partId = param.Value<string>(ParamFields._partId);
            var partCode = param.Value<string>(ParamFields._partCode);
            dynamic data = null;

            if (string.IsNullOrEmpty(partId))
            {
                data = repository.Invoke(CSIs.Get_Part_Detail_Standard, new { partCode, brandCode });
            }
            else
            {
                data = repository.Invoke(CSIs.Get_Usage_Detail_Standard, param);
            }
            if (data == null) return null;
            // 1、基本信息赋值
            Query_Part_DetailResult result = JObject.FromObject(data).ToObject<Query_Part_DetailResult>();

            
            //4.配件附加属性处理
            var props = new List<Query_Part_DetailResult._prop>
            {
                new Query_Part_DetailResult._prop { key = "件数", value = result.quantity ?? string.Empty },
            };
            result.props = props.Where(q => !string.IsNullOrEmpty(q.value)).ToList();
            return result;
        }
    }
}
